home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 May: Tool Chest / Developer CD Series May 1996 (Tool Chest) (Apple Computer) (1996).iso / Tool Chest / Development Tools & Languages / • Other Platforms / PCCTS 1.31 / antlr / lex.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-03-10  |  18.7 KB  |  761 lines  |  [TEXT/MPS ]

  1. /*
  2.  * lex.c    --    Generate all of the lexical type files: parser.dlg tokens.h
  3.  *
  4.  * $Id: lex.c,v 1.13 1994/12/31 21:02:55 parrt Exp parrt $
  5.  * $Revision: 1.13 $
  6.  *
  7.  * SOFTWARE RIGHTS
  8.  *
  9.  * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
  10.  * Set (PCCTS) -- PCCTS is in the public domain.  An individual or
  11.  * company may do whatever they wish with source code distributed with
  12.  * PCCTS or the code generated by PCCTS, including the incorporation of
  13.  * PCCTS, or its output, into commerical software.
  14.  * 
  15.  * We encourage users to develop software with PCCTS.  However, we do ask
  16.  * that credit is given to us for developing PCCTS.  By "credit",
  17.  * we mean that if you incorporate our source code into one of your
  18.  * programs (commercial product, research project, or otherwise) that you
  19.  * acknowledge this fact somewhere in the documentation, research report,
  20.  * etc...  If you like PCCTS and have developed a nice tool with the
  21.  * output, please mention that you developed it using PCCTS.  In
  22.  * addition, we ask that this header remain intact in our source code.
  23.  * As long as these guidelines are kept, we expect to continue enhancing
  24.  * this system and expect to make other tools available as they are
  25.  * completed.
  26.  *
  27.  * ANTLR 1.31
  28.  * Terence Parr
  29.  * Parr Research Corporation
  30.  * with Purdue University and AHPCRC, University of Minnesota
  31.  * 1989-1995
  32.  */
  33. #include <stdio.h>
  34. #include <ctype.h>
  35. #ifdef __cplusplus
  36. #ifndef __STDC__
  37. #define __STDC__
  38. #endif
  39. #endif
  40. #include "set.h"
  41. #include "syn.h"
  42. #include "hash.h"
  43. #include "generic.h"
  44.  
  45. #define DLGErrorString "invalid token"
  46.  
  47. /* Generate a complete lexical description of the lexemes found in the grammar */
  48. void
  49. #ifdef __STDC__
  50. genLexDescr( void )
  51. #else
  52. genLexDescr( )
  53. #endif
  54. {
  55.     ListNode *p;
  56.     FILE *dlgFile = fopen(OutMetaName(DlgFileName), "w");
  57.     require(dlgFile!=NULL, eMsg1("genLexFile: cannot open %s", OutMetaName(DlgFileName)) );
  58.     special_fopen_actions(OutMetaName(DlgFileName));
  59.  
  60.     fprintf(dlgFile, "<<\n");
  61.     fprintf(dlgFile, "/* %s -- DLG Description of scanner\n", DlgFileName);
  62.     fprintf(dlgFile, " *\n");
  63.     fprintf(dlgFile, " * Generated from:");
  64.     {int i; for (i=0; i<NumFiles; i++) fprintf(dlgFile, " %s", FileStr[i]);}
  65.     fprintf(dlgFile, "\n");
  66.     fprintf(dlgFile, " *\n");
  67.     fprintf(dlgFile, " * Terence Parr, Will Cohen, and Hank Dietz: 1989-1994\n");
  68.     fprintf(dlgFile, " * Purdue University Electrical Engineering\n");
  69.     fprintf(dlgFile, " * With AHPCRC, University of Minnesota\n");
  70.     fprintf(dlgFile, " * ANTLR Version %s\n", Version);
  71.     fprintf(dlgFile, " */\n\n");
  72.     if ( GenCC )
  73.     {
  74.         if ( !UserDefdTokens ) fprintf(dlgFile, "#include \"%s\"\n", DefFileName);
  75.         else fprintf(dlgFile, "#include %s\n", UserTokenDefsFile);
  76.         fprintf(dlgFile, "#include \"%s\"\n", ATOKEN_H);
  77.         if ( GenAST ) fprintf(dlgFile, "#include \"%s\"\n", ASTBASE_H);
  78.         if ( HdrAction != NULL ) dumpAction( HdrAction, dlgFile, 0, -1, 0, 1 );
  79.     }
  80.     else
  81.     {
  82.         fprintf(dlgFile, "#include <stdio.h>\n");
  83.         fprintf(dlgFile, "#define ANTLR_VERSION    %s\n", VersionDef);
  84.         if ( strcmp(ParserName, DefaultParserName)!=0 )
  85.             fprintf(dlgFile, "#define %s %s\n", DefaultParserName, ParserName);
  86.         if ( strcmp(ParserName, DefaultParserName)!=0 )
  87.             fprintf(dlgFile, "#include \"%s\"\n", RemapFileName);
  88.         if ( HdrAction != NULL ) dumpAction( HdrAction, dlgFile, 0, -1, 0, 1 );
  89.         if ( FoundGuessBlk )
  90.         {
  91.             fprintf(dlgFile, "#define ZZCAN_GUESS\n");
  92.             fprintf(dlgFile, "#include <setjmp.h>\n");
  93.         }
  94.         if ( OutputLL_k > 1 ) fprintf(dlgFile, "#define LL_K %d\n", OutputLL_k);
  95.         if ( DemandLookahead ) fprintf(dlgFile, "#define DEMAND_LOOK\n");
  96.         fprintf(dlgFile, "#include \"antlr.h\"\n");
  97.         if ( GenAST ) {
  98.             fprintf(dlgFile, "#include \"ast.h\"\n");
  99.         }
  100.         if ( UserDefdTokens )
  101.             fprintf(dlgFile, "#include %s\n", UserTokenDefsFile);
  102.         /* still need this one as it has the func prototypes */
  103.         fprintf(dlgFile, "#include \"%s\"\n", DefFileName);
  104.         fprintf(dlgFile, "#include \"dlgdef.h\"\n");
  105.         fprintf(dlgFile, "LOOKAHEAD\n");
  106.         fprintf(dlgFile, "void zzerraction()\n");
  107.         fprintf(dlgFile, "{\n");
  108.         fprintf(dlgFile, "\t(*zzerr)(\"%s\");\n", DLGErrorString);
  109.         fprintf(dlgFile, "\tzzadvance();\n");
  110.         fprintf(dlgFile, "\tzzskip();\n");
  111.         fprintf(dlgFile, "}\n");
  112.     }
  113.     fprintf(dlgFile, ">>\n\n");
  114.  
  115.     /* dump all actions */
  116.     if (LexActions != NULL)
  117.     {
  118.         for (p = LexActions->next; p!=NULL; p=p->next)
  119.         {
  120.             fprintf(dlgFile, "<<\n");
  121.             dumpAction( (char *)p->elem, dlgFile, 0, -1, 0, 1 );
  122.             fprintf(dlgFile, ">>\n");
  123.         }
  124.     }
  125.     /* dump all regular expression rules/actions (skip sentinel node) */
  126.     if ( ExprOrder == NULL ) {
  127.         warnNoFL("no regular expressions found in grammar");
  128.     }
  129.     else dumpLexClasses(dlgFile);
  130.     fprintf(dlgFile, "%%%%\n");
  131.     fclose( dlgFile );
  132. }
  133.  
  134. /* For each lexical class, scan ExprOrder looking for expressions
  135.  * in that lexical class.  Print out only those that match.
  136.  * Each element of the ExprOrder list has both an expr and an lclass
  137.  * field.
  138.  */
  139. void
  140. #ifdef __STDC__
  141. dumpLexClasses( FILE *dlgFile )
  142. #else
  143. dumpLexClasses( dlgFile )
  144. FILE *dlgFile;
  145. #endif
  146. {
  147.     int i;
  148.     TermEntry *t;
  149.     ListNode *p;
  150.     Expr *q;
  151.  
  152.     for (i=0; i<NumLexClasses; i++)
  153.     {
  154.         fprintf(dlgFile, "\n%%%%%s\n\n", lclass[i].classnum);
  155.         for (p=ExprOrder->next; p!=NULL; p=p->next)
  156.         {
  157.             q = (Expr *) p->elem;
  158.             if ( q->lclass != i ) continue;
  159.             lexmode(i);
  160.             t = (TermEntry *) hash_get(Texpr, q->expr);
  161.             require(t!=NULL, eMsg1("genLexDescr: rexpr %s not in hash table",q->expr) );
  162.             if ( t->token == EpToken ) continue;
  163.             fprintf(dlgFile, "%s\n\t<<\n", StripQuotes(q->expr));
  164.             /* replace " killed by StripQuotes() */
  165.             q->expr[ strlen(q->expr) ] = '"';
  166.             if ( !GenCC ) {
  167.                 if ( TokenString(t->token) != NULL )
  168.                     fprintf(dlgFile, "\t\tNLA = %s;\n", TokenString(t->token));
  169.                 else
  170.                     fprintf(dlgFile, "\t\tNLA = %d;\n", t->token);
  171.             }
  172.             if ( t->action != NULL ) dumpAction( t->action, dlgFile, 2,-1,0,1 );
  173.             if ( GenCC ) {
  174.                 if ( TokenString(t->token) != NULL )
  175.                     fprintf(dlgFile, "\t\treturn %s;\n", TokenString(t->token));
  176.                 else
  177.                     fprintf(dlgFile, "\t\treturn (TokenType)%d;\n", t->token);
  178.             }
  179.             fprintf(dlgFile, "\t>>\n\n");
  180.         }
  181.     }
  182. }
  183.  
  184. /* Generate a list of #defines && list of struct definitions for
  185.  * aggregate retv's */
  186. void
  187. #ifdef __STDC__
  188. genDefFile( void )
  189. #else
  190. genDefFile( )
  191. #endif
  192. {
  193.     int i;
  194.  
  195.     /* If C++ mode and #tokdef used, then don't need anything in here since
  196.      * C++ puts all definitions in the class file name.
  197.      */
  198.     if ( GenCC && UserTokenDefsFile ) return;
  199.  
  200.     DefFile = fopen(OutMetaName(DefFileName), "w");
  201.     require(DefFile!=NULL, eMsg1("genDefFile: cannot open %s", OutMetaName(DefFileName)) );
  202.     special_fopen_actions(OutMetaName(DefFileName));
  203.  
  204.     fprintf(DefFile, "#ifndef %s\n", gate_symbol(DefFileName));
  205.     fprintf(DefFile, "#define %s\n", gate_symbol(DefFileName));
  206.  
  207.     fprintf(DefFile, "/* %s -- List of labelled tokens and stuff\n", DefFileName);
  208.     fprintf(DefFile, " *\n");
  209.     fprintf(DefFile, " * Generated from:");
  210.     for (i=0; i<NumFiles; i++) fprintf(DefFile, " %s", FileStr[i]);
  211.     fprintf(DefFile, "\n");
  212.     fprintf(DefFile, " *\n");
  213.     fprintf(DefFile, " * Terence Parr, Will Cohen, and Hank Dietz: 1989-1994\n");
  214.     fprintf(DefFile, " * Purdue University Electrical Engineering\n");
  215.     fprintf(DefFile, " * ANTLR Version %s\n", Version);
  216.     fprintf(DefFile, " */\n");
  217.  
  218.     if ( !GenCC && LexGen ) {
  219.         fprintf(DefFile,"#define zzEOF_TOKEN %d\n",
  220.                 TokenInd!=NULL?TokenInd[EofToken]:EofToken);
  221.     }
  222.  
  223.     if ( !UserDefdTokens )
  224.     {
  225.         int first=1;
  226.  
  227.         if ( GenCC ) fprintf(DefFile, "enum TokenType {\n");
  228.         for (i=1; i<TokenNum; i++)
  229.         {
  230.             /* Don't do EpToken or expr w/o labels */
  231.             if ( TokenString(i)!=NULL && i != EpToken )
  232.             {
  233.                 TermEntry *p;
  234.                 
  235.                 if ( WarningLevel>1 )
  236.                 {
  237.                     int j;
  238.                     /* look in all lexclasses for the reg expr */
  239.                     for (j=0; j<NumLexClasses; j++)
  240.                     {
  241.                         lexmode(j);
  242.                         if ( ExprString(i)!=NULL ) break;
  243.                     }
  244.                     if ( j>=NumLexClasses )
  245.                     {
  246.                         warnNoFL(eMsg1("token label has no associated rexpr: %s",TokenString(i)));
  247.                     }
  248.                 }
  249.                 require((p=(TermEntry *)hash_get(Tname, TokenString(i))) != NULL,
  250.                         "token not in sym tab when it should be");
  251.                 if ( !p->classname )
  252.                 {
  253.                     if ( GenCC ) {
  254.                         if ( !first ) fprintf(DefFile, ",\n");
  255.                         first = 0;
  256.                         fprintf(DefFile, "\t%s=%d", TokenString(i), i);
  257.                     }
  258.                     else
  259.                         fprintf(DefFile, "#define %s %d\n", TokenString(i), i);
  260.                 }
  261.             }
  262.         }
  263.         if ( GenCC ) fprintf(DefFile, "};\n");
  264.     }
  265.  
  266.     if ( !GenCC ) GenRulePrototypes(DefFile, SynDiag);
  267.  
  268.     fprintf(DefFile, "\n#endif\n");
  269. }
  270.  
  271. void
  272. #ifdef __STDC__
  273. GenRemapFile( void )
  274. #else
  275. GenRemapFile( )
  276. #endif
  277. {
  278.     if ( strcmp(ParserName, DefaultParserName)!=0 )
  279.     {
  280.         FILE *f;
  281.         int i;
  282.  
  283.         f = fopen(OutMetaName(RemapFileName), "w");
  284.         require(f!=NULL, eMsg1("GenRemapFile: cannot open %s", OutMetaName(RemapFileName)) );
  285.         special_fopen_actions(OutMetaName(RemapFileName));
  286.  
  287.         fprintf(f, "/* %s -- List of symbols to remap\n", RemapFileName);
  288.         fprintf(f, " *\n");
  289.         fprintf(f, " * Generated from:");
  290.         for (i=0; i<NumFiles; i++) fprintf(f, " %s", FileStr[i]);
  291.         fprintf(f, "\n");
  292.         fprintf(f, " *\n");
  293.         fprintf(f, " * Terence Parr, Will Cohen, and Hank Dietz: 1989-1994\n");
  294.         fprintf(f, " * Purdue University Electrical Engineering\n");
  295.         fprintf(f, " * ANTLR Version %s\n", Version);
  296.         fprintf(f, " */\n");
  297.  
  298.         GenRuleFuncRedefs(f, SynDiag);
  299.         GenPredefinedSymbolRedefs(f);
  300.         if ( GenAST ) GenASTSymbolRedefs(f);
  301.         GenSetRedefs(f);
  302.  
  303.         fclose(f);
  304.     }
  305. }
  306.  
  307. /* Generate a bunch of #defines that rename all functions to be "ParserName_func" */
  308. void
  309. #ifdef __STDC__
  310. GenRuleFuncRedefs( FILE *f, Junction *p )
  311. #else
  312. GenRuleFuncRedefs( f, p )
  313. FILE *f;
  314. Junction *p;
  315. #endif
  316. {
  317.     fprintf(f, "\n/* rename rule functions to be 'ParserName_func' */\n");
  318.     while ( p!=NULL )
  319.     {
  320.         fprintf(f, "#define %s %s_%s\n", p->rname, ParserName, p->rname);
  321.         p = (Junction *)p->p2;
  322.     }
  323. }
  324.  
  325. /* Generate a bunch of #defines that rename all standard symbols to be
  326.  * "ParserName_symbol".  The list of standard symbols to change is in
  327.  * globals.c.
  328.  */
  329. void
  330. #ifdef __STDC__
  331. GenPredefinedSymbolRedefs( FILE *f )
  332. #else
  333. GenPredefinedSymbolRedefs( f )
  334. FILE *f;
  335. #endif
  336. {
  337.     char **p;
  338.  
  339.     fprintf(f, "\n/* rename PCCTS-supplied symbols to be 'ParserName_symbol' */\n");
  340.     for (p = &StandardSymbols[0]; *p!=NULL; p++)
  341.     {
  342.         fprintf(f, "#define %s %s_%s\n", *p, ParserName, *p);
  343.     }
  344. }
  345.  
  346. /* Generate a bunch of #defines that rename all AST symbols to be
  347.  * "ParserName_symbol".  The list of AST symbols to change is in
  348.  * globals.c.
  349.  */
  350. void
  351. #ifdef __STDC__
  352. GenASTSymbolRedefs( FILE *f )
  353. #else
  354. GenASTSymbolRedefs( f )
  355. FILE *f;
  356. #endif
  357. {
  358.     char **p;
  359.  
  360.     fprintf(f, "\n/* rename PCCTS-supplied AST symbols to be 'ParserName_symbol' */\n");
  361.     for (p = &ASTSymbols[0]; *p!=NULL; p++)
  362.     {
  363.         fprintf(f, "#define %s %s_%s\n", *p, ParserName, *p);
  364.     }
  365. }
  366.  
  367. /* redefine all sets generated by ANTLR; WARNING:  'zzerr', 'setwd' must match
  368.  * use in bits.c (DumpSetWd() etc...)
  369.  */
  370. void
  371. #ifdef __STDC__
  372. GenSetRedefs( FILE *f )
  373. #else
  374. GenSetRedefs( f )
  375. FILE *f;
  376. #endif
  377. {
  378.     int i;
  379.  
  380.     for (i=1; i<=wordnum; i++)
  381.     {
  382.         fprintf(f, "#define setwd%d %s_setwd%d\n", i, ParserName, i);
  383.     }
  384.     for (i=1; i<=esetnum; i++)
  385.     {
  386.         fprintf(f, "#define zzerr%d %s_err%d\n", i, ParserName, i);
  387.     }
  388. }
  389.  
  390. /* Find all return types/parameters that require structs and def
  391.  * all rules with ret types.
  392.  */
  393. void
  394. #ifdef __STDC__
  395. GenRulePrototypes( FILE *f, Junction *p )
  396. #else
  397. GenRulePrototypes( f, p )
  398. FILE *f;
  399. Junction *p;
  400. #endif
  401. {
  402.     int i;
  403.  
  404.     i = 1;
  405.     while ( p!=NULL )
  406.     {
  407.         if ( p->ret != NULL )
  408.         {
  409.             if ( HasComma(p->ret) )
  410.             {
  411.                 DumpRetValStruct(f, p->ret, i);
  412.             }
  413.             fprintf(f, "\n#ifdef __STDC__\n");
  414.             if ( HasComma(p->ret) )
  415.             {
  416.                 fprintf(f, "extern struct _rv%d", i);
  417.             }
  418.             else
  419.             {
  420.                 fprintf(f, "extern ");
  421.                 DumpType(p->ret, f);
  422.             }
  423.             fprintf(f, " %s%s(", RulePrefix, p->rname);
  424.             DumpANSIFunctionArgDef(f,p);
  425.             fprintf(f, ";\n");
  426. #ifdef OLD
  427.             if ( p->pdecl != NULL || GenAST )
  428.             {
  429.                 if ( GenAST ) {
  430.                     fprintf(f, "AST **%s",(p->pdecl!=NULL)?",":"");
  431.                 }
  432.                 if ( p->pdecl!=NULL ) fprintf(f, "%s", p->pdecl);
  433.             }
  434.             else fprintf(f, "void");
  435.             fprintf(f, ");\n");
  436. #endif
  437.             fprintf(f, "#else\n");
  438.             if ( HasComma(p->ret) )
  439.             {
  440.                 fprintf(f, "extern struct _rv%d", i);
  441.             }
  442.             else
  443.             {
  444.                 fprintf(f, "extern ");
  445.                 DumpType(p->ret, f);
  446.             }
  447.             fprintf(f, " %s%s();\n", RulePrefix, p->rname);
  448.             fprintf(f, "#endif\n");
  449.         }
  450.         else
  451.         {
  452.             fprintf(f, "\n#ifdef __STDC__\n");
  453.             fprintf(f, "void %s%s(", RulePrefix, p->rname);
  454.             DumpANSIFunctionArgDef(f,p);
  455.             fprintf(f, ";\n");
  456. #ifdef OLD
  457.             if ( p->pdecl != NULL || GenAST )
  458.             {
  459.                 if ( GenAST ) {
  460.                     fprintf(f, "AST **%s",(p->pdecl!=NULL)?",":"");
  461.                 }
  462.                 if ( p->pdecl!=NULL ) fprintf(f, "%s", p->pdecl);
  463.             }
  464.             else fprintf(f, "void");
  465.             fprintf(f, ");\n");
  466. #endif
  467.             fprintf(f, "#else\n");
  468.             fprintf(f, "extern void %s%s();\n", RulePrefix, p->rname);
  469.             fprintf(f, "#endif\n");
  470.         }
  471.         i++;
  472.         p = (Junction *)p->p2;
  473.     }
  474. }
  475.  
  476. /* Define all rules in the class.h file; generate any required
  477.  * struct definitions first, however.
  478.  */
  479. void
  480. #ifdef __STDC__
  481. GenRuleMemberDeclarationsForCC( FILE *f, Junction *q )
  482. #else
  483. GenRuleMemberDeclarationsForCC( f, q )
  484. FILE *f;
  485. Junction *q;
  486. #endif
  487. {
  488.     Junction *p = q;
  489.     int i;
  490.  
  491.     fprintf(f, "private:\n");
  492.  
  493.     /* Dump dflt handler declaration */
  494.     fprintf(f, "\tvoid zzdflthandlers( int _signal, int *_retsignal );\n\n");
  495.  
  496.     /* Dump return value structs */
  497.     i = 1;
  498.     while ( p!=NULL )
  499.     {
  500.         if ( p->ret != NULL )
  501.         {
  502.             if ( HasComma(p->ret) )
  503.             {
  504.                 DumpRetValStruct(f, p->ret, i);
  505.             }
  506.         }
  507.         i++;
  508.         p = (Junction *)p->p2;
  509.     }
  510.  
  511.     /* Dump member func defs && CONSTRUCTOR */
  512.     fprintf(f, "public:\n");
  513.     fprintf(f, "\t%s(ANTLRTokenBuffer *input);\n", CurrentClassName);
  514.     fprintf(f, "\t%s(ANTLRTokenBuffer *input, TokenType eof);\n",
  515.                CurrentClassName);
  516.  
  517.     i = 1;
  518.     p = q;
  519.     while ( p!=NULL )
  520.     {
  521.         if ( p->ret != NULL )
  522.         {
  523.             if ( HasComma(p->ret) )
  524.             {
  525.                 fprintf(f, "\tstruct _rv%d", i);
  526.             }
  527.             else
  528.             {
  529.                 fprintf(f, "\t");
  530.                 DumpType(p->ret, f);
  531.             }
  532.             fprintf(f, " %s(", p->rname);
  533.             DumpANSIFunctionArgDef(f,p);
  534.             fprintf(f, ";\n");
  535. #ifdef OLD
  536.             if ( p->pdecl != NULL || GenAST )
  537.             {
  538.                 if ( GenAST ) fprintf(f, "ASTBase **%s",(p->pdecl!=NULL)?",":"");
  539.                 if ( p->pdecl!=NULL ) fprintf(f, "%s", p->pdecl);
  540.             }
  541.             fprintf(f, ");\n");
  542. #endif
  543.         }
  544.         else
  545.         {
  546.             fprintf(f, "\tvoid %s(", p->rname);
  547.             DumpANSIFunctionArgDef(f,p);
  548.             fprintf(f, ";\n");
  549. #ifdef OLD
  550.             if ( p->pdecl != NULL || GenAST )
  551.             {
  552.                 if ( GenAST ) fprintf(f, "ASTBase **%s",(p->pdecl!=NULL)?",":"");
  553.                 if ( p->pdecl!=NULL ) fprintf(f, "%s", p->pdecl);
  554.             }
  555.             fprintf(f, ");\n");
  556. #endif
  557.         }
  558.         i++;
  559.         p = (Junction *)p->p2;
  560.     }
  561. }
  562.  
  563. /* Given a list of ANSI-style parameter declarations, print out a
  564.  * comma-separated list of the symbols (w/o types).
  565.  * Basically, we look for a comma, then work backwards until start of
  566.  * the symbol name.  Then print it out until 1st non-alnum char.  Now,
  567.  * move on to next parameter.
  568.  */
  569. void
  570. #ifdef __STDC__
  571. DumpListOfParmNames( char *pdecl, FILE *output )
  572. #else
  573. DumpListOfParmNames( pdecl, output )
  574. char *pdecl;
  575. FILE *output;
  576. #endif
  577. {
  578.     int firstTime = 1, done = 0;
  579.     require(output!=NULL, "DumpListOfParmNames: NULL parm");
  580.  
  581.     if ( pdecl == NULL ) return;
  582.     while ( !done )
  583.     {
  584.         if ( !firstTime ) putc(',', output);
  585.         done = DumpNextNameInDef(&pdecl, output);
  586.         firstTime = 0;
  587.     }
  588. }
  589.  
  590. /* given a list of parameters or return values, dump the next
  591.  * name to output.  Return 1 if last one just printed, 0 if more to go.
  592.  */
  593. int
  594. #ifdef __STDC__
  595. DumpNextNameInDef( char **q, FILE *output )
  596. #else
  597. DumpNextNameInDef( q, output )
  598. char **q;
  599. FILE *output;
  600. #endif
  601. {
  602.     char *p = *q;        /* where did we leave off? */
  603.     int done=0;
  604.  
  605.     while ( *p!='\0' && *p!=',' ) p++;        /* find end of decl */
  606.     if ( *p == '\0' ) done = 1;
  607.     while ( !isalnum(*p) && *p!='_' ) --p;    /* scan back until valid var character */
  608.     while ( isalnum(*p) || *p=='_' ) --p;    /* scan back until beginning of variable */
  609.     p++;                        /* move to start of variable */
  610.     while ( isalnum(*p) || *p=='_'  ) {putc(*p, output); p++;}
  611.     while ( *p!='\0' && *p!=',' ) p++;        /* find end of decl */
  612.     p++;                /* move past this parameter */
  613.  
  614.     *q = p;                /* record where we left off */
  615.     return done;
  616. }
  617.  
  618. /* Given a list of ANSI-style parameter declarations, dump K&R-style
  619.  * declarations, one per line for each parameter.  Basically, convert
  620.  * comma to semi-colon, newline.
  621.  */
  622. void
  623. #ifdef __STDC__
  624. DumpOldStyleParms( char *pdecl, FILE *output )
  625. #else
  626. DumpOldStyleParms( pdecl, output )
  627. char *pdecl;
  628. FILE *output;
  629. #endif
  630. {
  631.     require(output!=NULL, "DumpOldStyleParms: NULL parm");
  632.  
  633.     if ( pdecl == NULL ) return;
  634.     while ( *pdecl != '\0' )
  635.     {
  636.         if ( *pdecl == ',' )
  637.         {
  638.             pdecl++;
  639.             putc(';', output); putc('\n', output);
  640.             while ( *pdecl==' ' || *pdecl=='\t' || *pdecl=='\n' ) pdecl++;
  641.         }
  642.         else {putc(*pdecl, output); pdecl++;}
  643.     }
  644.     putc(';', output);
  645.     putc('\n', output);
  646. }
  647.  
  648. /* Take in a type definition (type + symbol) and print out type only */
  649. void
  650. #ifdef __STDC__
  651. DumpType( char *s, FILE *f )
  652. #else
  653. DumpType( s, f )
  654. char *s;
  655. FILE *f;
  656. #endif
  657. {
  658.     char *p, *end;
  659.     require(s!=NULL, "DumpType: invalid type string");
  660.  
  661.     p = &s[strlen(s)-1];        /* start at end of string and work back */
  662.     /* scan back until valid variable character */
  663.     while ( !isalnum(*p) && *p!='_' ) --p;
  664.     /* scan back until beginning of variable */
  665.     while ( isalnum(*p) || *p=='_' ) --p;
  666.     if ( p<=s )
  667.     {
  668.         warnNoFL(eMsg1("invalid parameter/return value: '%s'",s));
  669.         return;
  670.     }
  671.     end = p;                    /* here is where we stop printing alnum */
  672.     p = s;
  673.     while ( p!=end ) {putc(*p, f); p++;} /* dump until just before variable */
  674.     while ( *p!='\0' )                     /* dump rest w/o variable */
  675.     {
  676.         if ( !isalnum(*p) && *p!='_' ) putc(*p, f);
  677.         p++;
  678.     }
  679. }
  680.  
  681. /* check to see if string e is a word in string s */
  682. int
  683. #ifdef __STDC__
  684. strmember( char *s, char *e )
  685. #else
  686. strmember( s, e )
  687. char *s;
  688. char *e;
  689. #endif
  690. {
  691.     register char *p;
  692.     require(s!=NULL&&e!=NULL, "strmember: NULL string");
  693.     
  694.     if ( *e=='\0' ) return 1;   /* empty string is always member */
  695.     do {
  696.     while ( *s!='\0' && !isalnum(*s) && *s!='_' )
  697.     ++s;
  698.     p = e;
  699.     while ( *p!='\0' && *p==*s ) {p++; s++;}
  700.     if ( *p=='\0' ) {
  701.         if ( *s=='\0' ) return 1;
  702.         if ( !isalnum (*s) && *s != '_' ) return 1;
  703.     }
  704.     while ( isalnum(*s) || *s == '_' )
  705.     ++s;
  706.     } while ( *s!='\0' );
  707.     return 0;
  708. }
  709.  
  710. int
  711. #ifdef __STDC__
  712. HasComma( char *s )
  713. #else
  714. HasComma( s )
  715. char *s;
  716. #endif
  717. {
  718.     while (*s!='\0')
  719.         if ( *s++ == ',' ) return 1;
  720.     return 0;
  721. }
  722.  
  723. void
  724. #ifdef __STDC__
  725. DumpRetValStruct( FILE *f, char *ret, int i )
  726. #else
  727. DumpRetValStruct( f, ret, i )
  728. FILE *f;
  729. char *ret;
  730. int i;
  731. #endif
  732. {
  733.     fprintf(f, "\nstruct _rv%d {\n", i);
  734.     while ( *ret != '\0' )
  735.     {
  736.          while ( *ret==' ' || *ret=='\t' ) ret++; /* ignore white */
  737.          putc('\t', f);
  738.          while ( *ret!=',' && *ret!='\0' ) {putc(*ret,f); ret++;}
  739.          if ( *ret == ',' ) {putc(';', f); putc('\n', f); ret++;}
  740.     }
  741.     fprintf(f, ";\n};\n");
  742. }
  743.  
  744. /* given "s" yield s -- DESTRUCTIVE (we modify s if starts with " else return s) */
  745. char *
  746. #ifdef __STDC__
  747. StripQuotes( char *s )
  748. #else
  749. StripQuotes( s )
  750. char *s;
  751. #endif
  752. {
  753.     if ( *s == '"' )
  754.     {
  755.         s[ strlen(s)-1 ] = '\0';    /* remove last quote */
  756.         return( s+1 );                /* return address past initial quote */
  757.     }
  758.     return( s );
  759. }
  760.  
  761.